#pragma once

#include "IDataEntity.h"
#include "IPropertyChangeNotify.h"

template<typename T>
class DataEntity : public T, public IPropertyChangeNotify
{
public:
	DataEntity(){m_connection = NULL; m_id = OBJID_NULL;}
	virtual ~DataEntity(){}

	BEGIN_DEFINE_CLASS(CLASSID_NULL)
		DEFINE_INTERFACE_ENTRY(IDataEntity)
		DEFINE_INTERFACE_ENTRY(IPropertyChangeNotify)
	END_DEFINE_CLASS()

	virtual void Create(IConnection* connection,objectid id) {m_connection = connection; m_id = id;}
	virtual vresult Serialize(bool loading,IFileStream* stream) {loading; stream; return err_notimplement;}
	virtual void Dispose() {}

	virtual objectid GetID()const {return m_id; }
	virtual bool IsNull() const{return false;}

	virtual String GetEntityName() const= 0;
	virtual void SetEntityName(const String& /*value*/) {}

	event_implement(PropertyChangedEventHandler,PropertyChanged)
	event_implement(PropertyChangingEventHandler,PropertyChanging)

protected:
	IConnection* GetConnection() const {return m_connection;}
	uint32 GetChildren(objectarray& children) const
	{
		objectidarray childrenids;
		if (!GetConnection()->FindChildren(GetID(),childrenids))
			return 0u;

		objectidarray::const_iterator itbegin = childrenids.begin();
		objectidarray::const_iterator itend = childrenids.end();
		for (; itbegin != itend; ++itbegin)
			children.push_back(GetConnection()->FindObject(*itbegin));

		return children.size();
	}
	IObject* Self() const
	{
		IObject* self = NULL;
		((IPropertyChangeNotify*)this)->QueryObject(&self);
		return self;
	}

private:
	IConnection* m_connection;
	objectid m_id;
	String m_name;
};